import React, { createRef, useRef, useEffect } from 'react';
import { Row, Col } from 'antd';
import styles from './index.less';
import CodeMirror from '@uiw/react-codemirror';
import 'codemirror/keymap/sublime';
import 'codemirror/mode/xml/xml';
import 'codemirror/theme/xq-light.css';

import { validateXML } from '@/utils/validateXML.js';

// 添加高亮
import 'codemirror/addon/selection/active-line';
import 'codemirror/addon/fold/foldcode';
import 'codemirror/addon/fold/foldgutter';
import vkbeautify from 'vkbeautify';
import { useDebounceFn } from '@umijs/hooks';

export default props => {
  const {
    code,
    lineWidget = [],
    forwordRef: actionRef,
    onChange,
    onContextmenu,
    mode,
    readOnly,
    theme,
    ...rest
  } = props;
  //防抖
  const { run } = useDebounceFn((newCode, ref) => {
    onChange(newCode, ref);
  }, 500);
  let widgets = [];
  const editorRef = useRef();

  const clearHints = () => {
    const editor = editorRef?.current?.editor;
    for (var i = 0; i < widgets.length; ++i) {
      editor.removeLineWidget(widgets[i]);
    }

    widgets.length = 0;
  };

  useEffect(() => {
    if (lineWidget[0]) {
      addHints(lineWidget);
    }
    return () => {
      clearHints();
    };
  }, [lineWidget]);

  const addHints = (messages = []) => {
    const editor = editorRef?.current?.editor;
    clearHints();
    editor.operation(() => {
      for (var i = 0; i < messages.length; ++i) {
        var err = messages[i];
        if (!err) continue;
        var msg = document.createElement('div');
        var icon = msg.appendChild(document.createElement('span'));
        icon.innerHTML = '!!';
        icon.className = styles['lint-error-icon'];
        msg.appendChild(document.createTextNode(err.message));
        msg.className = styles['lint-error'];
        widgets.push(
          editor.addLineWidget(err.line - 1, msg, {
            above: false,
            coverGutter: false,
            noHScroll: true,
          }),
        );
      }
    });
  };

  //右键事件
  const handleContextmenu = (Editor, e) => {
    e.preventDefault();
    //右键事件不失去聚焦
    let listSelections = Editor.doc.listSelections();
    Editor.doc.setSelections(listSelections[0]);
    Editor.doc.cm.focus();
    onContextmenu && onContextmenu(Editor, e);
  };

  useEffect(() => {
    if (actionRef) {
      const userAction = {
        addHints,
        clearHints,
        ...editorRef.current,
      };
      if (actionRef && typeof actionRef === 'function') {
        actionRef(userAction);
      }
      if (actionRef && typeof actionRef !== 'function') {
        actionRef.current = userAction;
      }
    }
  }, []);

  let timer = null;
  return (
    <div style={{ height: '100%' }} className={styles['codeMirror-wrap']}>
      <CodeMirror
        {...rest}
        value={code}
        ref={editorRef}
        onContextmenu={handleContextmenu}
        onChange={(ref, aa) => {
          if (!onChange) return;
          const newCode = ref.getValue();
          // clearTimeout(timer);
          // timer = setTimeout(() => {
          //   const validate = validateXML(newCode);
          //   validate.error_code !== 0
          //     ? updateHints(ref, [{ message: validate.reason, line: validate.error_line - 1 }])
          //     : clearHints(ref);
          // }, 300);

          if (code !== newCode) {
            run(newCode, ref);
          }
        }}
        autoFocus={true}
        options={{
          readOnly: readOnly || false,
          styleActiveLine: true,
          theme: theme || 'xq-light',
          keyMap: 'sublime',
          lineNumbers: true,
          lineWrapping: true,
          mode: mode || 'xml',
          foldGutter: true,
          gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
        }}
      />
    </div>
  );
};
